package com.gongj.stream.demo1;

import org.junit.Test;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Stream 的终止操作
 */
public class Demo3 {

    List<String> list = Arrays.asList("bb","aa","cc","dd","d","c","da");
    List<Integer> numberList = Arrays.asList(1,23,33,4,5,66,21);

    List<Employee> employees = Arrays.asList(
            new Employee("张三",18,9999.99),
            new Employee("李四",38,5555.55),
            new Employee("王五",50,6666.66),
            new Employee("赵六",15,3333.33),
            new Employee("田七",18,7777.77)
    );
    @Test
    public void test20(){
        String collect = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",","这些人：","他们好棒"));
        System.out.println("str:" + collect);
    }



    @Test
    public void test19(){
        IntSummaryStatistics collect = employees.stream()
                .collect(Collectors.summarizingInt(Employee::getAge));
        System.out.println("个数" + collect.getCount());
        System.out.println("求和" + collect.getSum());
        System.out.println("最大值" + collect.getMax());
        System.out.println("平均值" + collect.getAverage());
        System.out.println("最小值" + collect.getMin());
    }

    //根据true或false进行分区
    @Test
    public void test18(){
        Map<Boolean, List<Employee>> collect = employees.stream()
                .collect(Collectors.partitioningBy(e -> e.getSalary() > 7000));
        for(Map.Entry<Boolean,List<Employee>> map : collect.entrySet()){
            Boolean key = map.getKey();
            List<Employee> value = map.getValue();
            for (Employee employee : value) {
                System.out.println("key=" +key + ",value = "+employee);
            }
        }
    }

    //根据年龄进行分组
    @Test
    public void test17(){
        Map<Integer, List<Employee>> collect = employees.stream()
                .collect(Collectors.groupingBy(Employee::getAge));
        for(Map.Entry<Integer,List<Employee>> map : collect.entrySet()){
            Integer key = map.getKey();
            List<Employee> value = map.getValue();
            for (Employee employee : value) {
                System.out.println("key=" +key + ",value = "+employee);
            }
        }
    }

    //获取到员工的姓名并放入集合中
    @Test
    public void test14(){
        List<String> collect = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        collect.forEach(System.out::println);
    }
    @Test
    public void test15(){
        HashSet<String> hs = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));
        hs.forEach(System.out::println);
    }

    @Test
    public void test16(){
        //元素的个数
        Long l = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.counting());
        System.out.println("个数" + l);
        //求和
        Double sum = employees.stream()
                .collect(Collectors.summingDouble(Employee::getAge));
        System.out.println("平均值" + sum);
        //平均值
        Double avg = employees.stream()
                .collect(Collectors.averagingDouble(Employee::getAge));
        System.out.println("平均值" + avg);
        //获得年龄最大的员工信息
        Optional<Employee> collect = employees.stream()
                .collect(Collectors.maxBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
        System.out.println("获得年龄最大的员工信息" + collect.get());
    }
    @Test
    public void test6(){
        long count = numberList.stream()
                .count();
        System.out.println(count);
    }

    @Test
    public void test7(){
        Optional<Integer> max = numberList.stream()
                .max(Integer::compareTo);
        System.out.println(max.get());
    }
    @Test
    public void test8(){
        Optional<Integer> max = numberList.stream()
                .min(Integer::compareTo);
        System.out.println(max.get());
    }
    @Test
    public void test1(){
        boolean aa = list.stream()
                .allMatch(obj -> obj.equals("aa"));
        System.out.println(aa);
    }

    @Test
    public void test2(){
        boolean aa = list.stream()
                .anyMatch(obj -> obj.equals("aa"));
        System.out.println(aa);
    }

    @Test
    public void test3(){
        boolean aa = list.stream()
                .noneMatch(obj -> obj.equals("aa"));
        System.out.println(aa);
    }

    @Test
    public void test4(){
        Optional<String> first = list.stream()
                .findFirst();
        System.out.println(first.get());
    }

    @Test
    public void test5(){
        Optional<String> first = list.parallelStream()
                .findAny();
        System.out.println(first.get());
    }

    List<Integer> numberList2 = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
    @Test
    public void test9(){
        Integer reduce = numberList2.stream()
                .reduce(10, (x1, x2) -> x1 + x2);
        System.out.println(reduce);
    }

    @Test
    public void test10(){
        Optional<Integer> reduce = numberList2.stream()
                .reduce(Integer::sum);
        System.out.println(reduce.get());
    }

    @Test
    public void test11(){

        ArrayList<Integer> reduce = numberList2.stream().reduce(new ArrayList<Integer>(),
                new BiFunction<ArrayList<Integer>, Integer, ArrayList<Integer>>() {
                    @Override
                    public ArrayList<Integer> apply(ArrayList<Integer> u, Integer s) {
                        u.add(s);
                        return u;
                    }
                }, new BinaryOperator<ArrayList<Integer>>() {
                    @Override
                    public ArrayList<Integer> apply(ArrayList<Integer> strings, ArrayList<Integer> strings2) {
                        strings.add(8888);
                        return strings;
                    }
                });
        System.out.println(reduce);
    }

    @Test
    public void test12(){

        List<Integer> reduce = numberList2.parallelStream().reduce(Collections.synchronizedList(new ArrayList<>(16)),
                new BiFunction<List<Integer>, Integer, List<Integer>>() {
                    @Override
                    public List<Integer> apply(List<Integer> u, Integer s) {
                        u.add(s);
                        return u;
                    }
                }, new BinaryOperator<List<Integer>>() {
                    @Override
                    public List<Integer> apply(List<Integer> strings, List<Integer> strings2) {
                        strings.add(8888);
                        return strings;
                    }
                });
        System.out.println(reduce);
    }

    @Test
    public void test13(){
        List<Integer> numberList3 = Arrays.asList(1,2,3);

        Stream<Integer> stream = numberList3.parallelStream();
        System.out.println(stream.reduce(4, new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer, Integer integer2) {
                        return integer + integer2;
                    }
                }
                , new BinaryOperator<Integer>() {
                    @Override
                    public Integer apply(Integer integer, Integer integer2) {
                        return integer + integer2;
                    }
                }));
    }

}
